package org.orarriinae.common.web.error;


import lombok.extern.slf4j.Slf4j;
import org.orarriinae.common.base.exception.ServiceException;
import org.orarriinae.common.utils.constant.StringConstant;
import org.orarriinae.common.web.result.ResponseBean;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.multipart.MaxUploadSizeExceededException;


import javax.naming.SizeLimitExceededException;
import java.nio.file.AccessDeniedException;
import java.util.HashMap;
import java.util.Map;


/**
 * 统一异常拦截
 *
 * @author xj
 * @author Wang Chengwei
 * @since  1.0
 */
@SuppressWarnings("java:S1610")
@Slf4j
public abstract class AbstractCommonExceptionHandler {

    /**
     * 数据异常返回
     *
     * @param serviceException 业务异常
     */
    @ExceptionHandler(value = ServiceException.class)
    public ResponseBean<String> serviceException(ServiceException serviceException) {
        ResponseBean<String> result = new ResponseBean<>();
        result.setErrorCode(serviceException.getErrorCode());
        result.setState(200);
        result.setMessage(serviceException.getMessage());
        log.error(serviceException.getErrorCode() + "-" + serviceException.getMessage(), serviceException);
        return result;
    }

    @ExceptionHandler(value = HttpClientErrorException.class)
    public ResponseBean<String> httpClientErrorException(HttpClientErrorException httpClientErrorException) {
        ResponseBean<String> result = new ResponseBean<>();
        result.setSuccess(false);
        result.setState(httpClientErrorException.getStatusCode().value());
        result.setErrorCode(httpClientErrorException.getStatusCode().toString());
        result.setMessage(httpClientErrorException.getMessage());
        log.error(httpClientErrorException.getMessage(), httpClientErrorException);
        return result;
    }

    /**
     * 参数异常校验返回
     *
     * @param bindException 参数绑定异常
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseBean<Map<String, String>> bindException(MethodArgumentNotValidException bindException) {
        ResponseBean<Map<String, String>> result = new ResponseBean<>();
        Map<String, String> errorMap = new HashMap<>(
                bindException.getBindingResult().getFieldErrors().size());

        for (FieldError error : bindException.getBindingResult().getFieldErrors()) {
            errorMap.put(error.getField(), error.getDefaultMessage());
        }
        result.setState(500);
        result.setSuccess(false);
        result.setErrorCode(StringConstant.DATA_ERROR);
        result.setData(errorMap);
        log.error(bindException.getMessage(), bindException);
        return result;
    }

    /**
     * 权限异常拦截
     *
     * @param exception 异常
     */
    @ExceptionHandler(AccessDeniedException.class)
    public ResponseBean<String> accessDeniedException(AccessDeniedException exception) {
        ResponseBean<String> result = new ResponseBean<>();
        result.setState(401);
        result.setErrorCode("401");
        result.setMessage(exception.getMessage());
        log.warn(exception.getMessage(), exception);
        return result;
    }

    /**
     * 文件上传异常
     *
     * @param exception 文件上传大小限制异常
     */
    @ExceptionHandler(MaxUploadSizeExceededException.class)
    public ResponseBean<String> uploadException(MaxUploadSizeExceededException exception)  {
        ResponseBean<String> result = new ResponseBean<>();
        result.setState(500);
        result.setErrorCode(StringConstant.DATA_ERROR);
        result.setMessage("最大上传文件为8M，上传文件大小超出限制!");
        log.error(exception.getMessage(), exception);
        return result;
    }

    /**
     * 文件过大
     *
     * @param exception 文件上传大小限制异常
     */
    @ExceptionHandler(SizeLimitExceededException.class)
    public ResponseBean<String> uploadException(SizeLimitExceededException exception)  {
        ResponseBean<String> result = new ResponseBean<>();
        result.setState(500);
        result.setErrorCode(StringConstant.DATA_ERROR);
        result.setMessage("最大上传文件为8M，上传文件大小超出限制!");
        log.error(exception.getMessage(), exception);
        return result;
    }

    /**
     * 所有异常拦截
     *
     * @param exception 异常
     */
    @ExceptionHandler(value = Exception.class)
    public ResponseBean<String> otherException(Exception exception) {
        ResponseBean<String> result = new ResponseBean<>();
        result.setState(500);
        result.setErrorCode(StringConstant.DATA_ERROR);
        result.setMessage("系统数据异常,请联系管理人员!");
        log.error(exception.getMessage(), exception);
        return result;
    }

}
